fixtSE
FixtSEFixtSE
Blog
Membership
Booking
About
Login

YoutubeInstagramRSSGithubPatreonPrivacy
Fixt â€ĸ Š 2025
Updated: Jan 19, 2025—7 min read

Beginner DIY ESPHome mmWave Presence Sensor

Written by: Fixt

If you're subscribed to our Channel
Login with your Google account to get our Smart Tutorial Experience!

TABLE OF CONTENTS
PrerequisitesHLK-LD2450 Sensor SpecsfixtSE DIY Sensor CaseHow to wire it upESPHome FirmwareYAML FilesHow to create zonesHLKRadarToolHow to use it on your dashboardPlotly GraphHow to automate with it

Featured

Easiest way to Control your Smart Home with AI: Ollama + Home AssistantEasiest way to Control your Smart Home with AI: Ollama + Home Assistant
ESPresense v3 - Room level presence detection with ESP32 and Home AssistantESPresense v3 - Room level presence detection with ESP32 and Home Assistant

Related

Tags

Home-Assistant
ESPHome
Dashboard
Tutorial
Presence-Detection
Sensor

If you like my work, please consider supporting me on Ko-fi! ☕🎉

← Back to the blog
mmWave Sensor
Back
Esp32 housing
Inside

Prerequisites
#

Using the affiliate links below helps support the channel and all the content I create 🎉🙌

  • ESP32 30 PIN Development Board
    • Amazon: (3 pack)
    • Aliexpress: (USB C / Micro USB)
  • HLK-LD2450 mmWave Radar Sensor
    • Amazon: (HLK-LD2450 Kit)
    • Aliexpress: (HLK-LD2450 Kit)
      • Option 1
      • Option 2

Optional

  • Dupont Cable
    • Amazon: (Dupont Cable Female to female)
    • Aliexpress: (Dupont Cable Female to female)
  • USB C Cable
    • Amazon: (2 Pack)
    • Aliexpress: (USB C Cable)
  • 5v charger
    • Amazon: (2 Pack)
    • Aliexpress: (5v charger)

HLK-LD2450 Sensor Specs
#

Back
  • Frequency: 24 GHz (ISM band)
  • Sensor Type: Millimeter wave radar
  • Detection Range: Up to 6 meters (approximately 8 meters in practical terms)
  • Module Size: Ultra-small, measuring 15mm x 44mm
  • Detection Angle: Âą60°
  • Pitch Angle: Âą35°

Additionally, the HLK-LD2450 sensor supports the following features:

  • Precise motion target localization and tracking: Distance, angle and speed.
  • Configurable Zones: It allows you to define up to 3 configurable zones for monitoring.
  • Multiple Connection Options: You can connect it using pin and socket interfaces.
  • Intelligent Algorithm Firmware: Utilizes FMCW waveforms and advanced signal processing technology.

fixtSE DIY Sensor Case
#

I'll keep adding more sensors to this case, so you can use it for other projects as well. đŸ› ī¸

You can get it on:

Or order it from:

Save $5 on your first order using our link: https://pcbway.com/g/lHR6if

How to wire it up
#

Wire Up
ESP32 BoardHLK-LD2450
VIN5v
TX2RX
RX2TX
GNDGND

ESPHome Firmware
#

Updated firmware to ESPHome 2024.12.4
Added OTA support

Not supported browser detected

Try a different browser!

The only difference between the two firmwares is the Bluetooth Proxy. If you don't need it, you can use the firmware without it.
You can find the documentation here

YAML Files
#

v1.2.0:
Added OTA support (deactivated by default)

Shop Content
YAML
TinkererFree
Member Banner

Available in our Store! Or, join the Tinkerer or Automation Hero tier to access our latest Shop Content for FREE!

  • Your support is invaluable in allowing us to continue creating the tutorials you like 😁🏠🎉
  • Click on the Patreon button below to become a member, and then log in with your Patreon Account on our website.

How to create zones
#

HLKRadarTool
#

How to use it on your dashboard
#

Plotly Graph
#

By dbuezas

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

Just replace mmwave_sensor with your sensor's name. Ej: mmwave_sensor_aac3 or mmwave_sensor_no_aac3 based on the firmware you flashed.

FirmwareSensor Name
With Bluetooth Proxymmwave_sensor
Without Bluetooth Proxymmwave_sensor_no

Custom Card

type: custom:plotly-graph
title: mmWave Radar Sensor
refresh_interval: 1
hours_to_show: current_day
layout:
  height: 230
  margin:
    l: 50
    r: 20
    t: 20
    b: 40
  showlegend: true
  xaxis:
    dtick: 100
    gridcolor: RGBA(200,200,200,0.15)
    zerolinecolor: RGBA(200,200,200,0.15)
    type: number
    fixedrange: true
    range:
      - 400
      - -400
  yaxis:
    dtick: 100
    gridcolor: RGBA(200,200,200,0.15)
    zerolinecolor: RGBA(200,200,200,0.15)
    scaleanchor: x
    scaleratio: 1
    fixedrange: true
    range:
      - 600
      - 0
entities:
  - entity: ''
    name: Target1
    marker:
      size: 12
    line:
      shape: spline
      width: 5
    x:
      - $ex hass.states["sensor.mmwave_sensor_target_1_x"].state /-10
    'y':
      - $ex hass.states["sensor.mmwave_sensor_target_1_y"].state /10
  - entity: ''
    name: Target2
    marker:
      size: 12
    line:
      shape: spline
      width: 5
    x:
      - $ex hass.states["sensor.mmwave_sensor_target_2_x"].state /-10
    'y':
      - $ex hass.states["sensor.mmwave_sensor_target_2_y"].state /10
  - entity: ''
    name: Target3
    marker:
      size: 12
    line:
      shape: spline
      width: 5
    x:
      - $ex hass.states["sensor.mmwave_sensor_target_3_x"].state /-10
    'y':
      - $ex hass.states["sensor.mmwave_sensor_target_3_y"].state /10
  - entity: ''
    name: Zone1
    mode: lines
    fill: toself
    fillcolor: RGBA(20,200,0,0.1)
    line:
      color: RGBA(20,200,0,0.2)
      shape: line
      width: 2
    x:
      - $ex hass.states["number.mmwave_sensor_zone_1_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_1_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_1_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_1_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_1_x1"].state /-10
    'y':
      - $ex hass.states["number.mmwave_sensor_zone_1_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_1_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_1_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_1_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_1_y1"].state /10
  - entity: ''
    name: Zone2
    mode: lines
    fill: toself
    fillcolor: RGBA(200,0,255,0.1)
    line:
      color: RGBA(200,0,255,0.2)
      shape: line
      width: 2
    x:
      - $ex hass.states["number.mmwave_sensor_zone_2_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_2_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_2_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_2_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_2_x1"].state /-10
    'y':
      - $ex hass.states["number.mmwave_sensor_zone_2_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_2_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_2_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_2_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_2_y1"].state /10
  - entity: ''
    name: Zone3
    mode: lines
    fill: toself
    fillcolor: RGBA(200,120,55,0.1)
    line:
      color: RGBA(200,120,55,0.2)
      shape: line
      width: 2
    x:
      - $ex hass.states["number.mmwave_sensor_zone_3_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_3_x1"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_3_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_3_x2"].state /-10
      - $ex hass.states["number.mmwave_sensor_zone_3_x1"].state /-10
    'y':
      - $ex hass.states["number.mmwave_sensor_zone_3_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_3_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_3_y2"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_3_y1"].state /10
      - $ex hass.states["number.mmwave_sensor_zone_3_y1"].state /10
  - entity: ''
    name: Coverage
    mode: lines
    fill: tonexty
    fillcolor: rgba(168, 216, 234, 0.15)
    line:
      shape: line
      width: 1
      dash: dot
    x:
      - 0
      - $ex 600 * Math.sin((2 * Math.PI)/360 * 60)
      - 450
      - 400
      - 300
      - 200
      - 100
      - 0
      - -100
      - -200
      - -300
      - -400
      - -450
      - $ex -600 * Math.sin((2 * Math.PI)/360 * 60)
      - 0
    'y':
      - 0
      - $ex 600 * Math.cos((2 * Math.PI)/360 * 60)
      - $ex Math.sqrt( 600**2 - 450**2 )
      - $ex Math.sqrt( 600**2 - 400**2 )
      - $ex Math.sqrt( 600**2 - 300**2 )
      - $ex Math.sqrt( 600**2 - 200**2 )
      - $ex Math.sqrt( 600**2 - 100**2 )
      - 600
      - $ex Math.sqrt( 600**2 - 100**2 )
      - $ex Math.sqrt( 600**2 - 200**2 )
      - $ex Math.sqrt( 600**2 - 300**2 )
      - $ex Math.sqrt( 600**2 - 400**2 )
      - $ex Math.sqrt( 600**2 - 450**2 )
      - $ex 600 * Math.cos((2 * Math.PI)/360 * 60)
      - 0
raw_plotly_config: true

How to automate with it
#

💡𐂷 Sensor Light

By Blacky
Documentation here

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Tags

Home-Assistant
ESPHome
Dashboard
Tutorial
Presence-Detection
Sensor
← Back to the blog

Featured

Easiest way to Control your Smart Home with AI: Ollama + Home AssistantEasiest way to Control your Smart Home with AI: Ollama + Home Assistant
ESPresense v3 - Room level presence detection with ESP32 and Home AssistantESPresense v3 - Room level presence detection with ESP32 and Home Assistant

Related

Tags

Home-Assistant
ESPHome
Dashboard
Tutorial
Presence-Detection
Sensor